﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using LASDesktop.Classes;
using LASDesktop.LASDBClasses;
using Microsoft.Win32;

namespace LASDesktop.ModuloInventario
{

    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class VisorDeArticulos : Window
    {
        private LASDBDataContext _db = new LASDBDataContext();
        private List<Foto> _listaFotos = new List<Foto>();
        private readonly Window _parent;
        private int _type;
        private int _currentImageIndex = 0;
        private int _currentProductId;
        private int _idEmpresa;

        #region Constructores

        /// <summary>
        /// Constructor para el diálogo: Agregar nuevo producto
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="idEmpresa"></param>
        public VisorDeArticulos(Window parent, int idEmpresa)
        {
            _parent = parent;
            _type = Constants.PRODUCT_VIEWER_ADD_TYPE;
            _idEmpresa = idEmpresa;
            InitializeComponent();
            SubmitButton.Content = Constants.PRODUCT_VIEWER_ADD_BUTTON;
            UploadMeasurementsList();
        }

        /// <summary>
        /// Constructor para el diálogo: Editar producto
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="producto"></param>
        /// <param name="idEmpresa"></param>
        public VisorDeArticulos(Window parent, Articulo producto, int idEmpresa)
        {
            _parent = parent;
            _currentProductId = producto.IdArticulo;
            _listaFotos = producto.Fotos.ToList();
            _type = Constants.PRODUCT_VIEWER_EDIT_TYPE;
            _idEmpresa = idEmpresa;
            InitializeComponent();
            SubmitButton.Content = Constants.PRODUCT_VIEWER_EDIT_BUTTON;
            UploadMeasurementsList();
            UploadProduct(producto);
        }
        #endregion

        /// <summary>
        /// Método que carga la lista de medidas en el combobox.
        /// </summary>
        private void UploadMeasurementsList()
        {
            try
            {
                var medidasResult =  _db.GetMeasurements().ToList();
                InputMeasurementUnit.ItemsSource = medidasResult;
                InputMeasurementUnit.DisplayMemberPath = "Nombre";
                InputMeasurementUnit.SelectedIndex = 0;
            }
            catch
            {
                //TODO: Error
            }
        }
        
        /// <summary>
        /// Carga el producto al formulario.
        /// </summary>
        /// <param name="producto"></param>
        private void UploadProduct(Articulo producto)
        {
            InputCode.Text = producto.CodigoUnico;
            InputComments.Text = producto.Comentario;
            InputDescription.Text = producto.Descripcion;
            var index = InputMeasurementUnit.Items.Cast<GetMeasurementsResult>().ToList().FindIndex(
                cmbi => cmbi.IdMedida==producto.IdMedida);
            InputMeasurementUnit.SelectedIndex = index;
            ChangeImage(1);
        }

        private void ChangeImage(int toIndex)
        {
            var index = toIndex-1;

            if (index < 0 && _listaFotos.Count == 0)
            {
                ImageCountText.Text = "0/0";
                return;
            }
            if (index < 0)
            {
                return;
            }
            if (_listaFotos.Count == 0)
            {
                ImageCountText.Text = "0/0";
            }
            else if (index > _listaFotos.Count-1)
            {
                return;
            }
            else
            {
                _currentImageIndex = toIndex;

                ImageCountText.Text = _currentImageIndex + "/" + _listaFotos.Count;
                LoadCurrentImage(_listaFotos[index].Foto1.ToArray(), CurrentImage);
            }
        }
        
        /// <summary>
        /// Método que agrega un nuevo producto a la base de datos
        /// </summary>
        private void AddNewProduct(Articulo newProduct)
        {
            try
            {
                _db.InsertProduct(newProduct.CodigoUnico, newProduct.Descripcion, newProduct.IdMedida,
                                  newProduct.Comentario, _idEmpresa);
                
                var lastProductId = (from articulo in _db.Articulos select articulo.IdArticulo).Max();

                foreach (var foto in _listaFotos)
                {
                    foto.IdArticulo = lastProductId;
                    _db.Fotos.InsertOnSubmit(foto);
                }
                _db.SubmitChanges();
            }
            catch
            {
                
            }
        }

        /// <summary>
        /// Método que edita un producto de la base de datos
        /// </summary>
        private void EditProduct(Articulo newProduct)
        {
            try
            {
               
                var oldProduct = _db.Articulos.First(p => p.IdArticulo== _currentProductId);
                oldProduct.Comentario = newProduct.Comentario;
                oldProduct.Descripcion = newProduct.Descripcion;
                oldProduct.IdMedida = newProduct.IdMedida;

                foreach (var foto in _listaFotos.Where(foto => foto.IdArticulo == 0))
                {
                    foto.IdArticulo = oldProduct.IdArticulo;
                    _db.Fotos.InsertOnSubmit(foto);
                }

                _db.SubmitChanges();
            }
            catch
            {
                
            }

        }

        /// <summary>
        /// Método que crea un nuevo producto a partir de los datos del
        /// formulario.
        /// </summary>
        /// <returns></returns>
        private Articulo CreateProductFromForm()
        {
            var nuevoArticulo = new Articulo()
                                         {
                                             CodigoUnico = InputCode.Text,
                                             Comentario = InputComments.Text,
                                             Descripcion = InputDescription.Text,
                                             IdMedida = ((GetMeasurementsResult)InputMeasurementUnit.SelectedItem).IdMedida
                                         };
            return nuevoArticulo;
        }


        #region GUI events
        /// <summary>
        /// Método que se dispara al presionar el botón de submit, si el tipo 
        /// del dialogo es de creacion crea el producto de lo contrario lo edita.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SubmitButtonClick(object sender, RoutedEventArgs e)
        {
            if (!IsSubmitValid()) return;

            var product = CreateProductFromForm();
            
            switch (_type)
            {
                case Constants.PRODUCT_VIEWER_ADD_TYPE:
                    AddNewProduct(product);
                    break;
                case Constants.PRODUCT_VIEWER_EDIT_TYPE:
                    EditProduct(product);
                    break;
            }

            var parent = (Inventario)_parent;
            parent.LoadProducts();
            parent.Overlay.Visibility = Visibility.Hidden;
            Close();
   
        }

        /// <summary>
        /// Método que dispara al presionar el botón agregar
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddClick(object sender, MouseButtonEventArgs e)
        {
            var imageBytes = GetByteFromDialog();
            if(imageBytes == null) return;
            _listaFotos.Add(new Foto(){Foto1 = imageBytes});
            ChangeImage(_listaFotos.Count);
        }

        private void LeftClick(object sender, MouseButtonEventArgs e)
        {
            ChangeImage(_currentImageIndex-1);
        }

        private void RightClick(object sender, MouseButtonEventArgs e)
        {
            ChangeImage(_currentImageIndex+1);
        }
		
		private void DeleteButton_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
		    var index = _currentImageIndex - 1;
            if (_currentImageIndex <= 1)
            {
                BitmapImage imagen = new BitmapImage();
                imagen.BeginInit();
                imagen.UriSource = new Uri(@"..\Graphics\ImageError.png", UriKind.Relative);
                imagen.EndInit();
                CurrentImage.Source = imagen; 
            }
            if (index < 0) return;
		    _db.DeleteImageFromProduct(_listaFotos[index].IdFoto);
            _listaFotos.RemoveAt(index);
            ChangeImage(index);
		}
        
        #endregion

        /// <summary>
        /// Método que verifica si los campos del formulario son correctos.
        /// </summary>
        /// <returns></returns>
        private bool IsSubmitValid()
        {
            //TODO: Verificar campos vacios
            return true;
        }

        public void LoadCurrentImage(byte[] imageBytes, Image image)
        {
            try
            {
                var bitImg = new BitmapImage();
                bitImg.BeginInit();
                var ms = new MemoryStream(imageBytes);
                bitImg.StreamSource = ms;
                bitImg.EndInit();
                image.Source = bitImg;
            }
            catch
            {
                
            }
            
        }

        public byte[] GetByteFromDialog()
        {
            var opendlg = new OpenFileDialog();
            byte[] fileInbytes;
            opendlg.Filter = "Image Files(*.BMP;*.JPG;*.GIF;*.PNG)|*.BMP;*.JPG;*.GIF;*.PNG";

            if (opendlg.ShowDialog() != true) return null;
            if (_listaFotos.Count == 5)
            {
                MessageBox.Show("El producto ya cuenta con 5 fotos asignadas, este es el limite por artículo","Limite de fotos alcanzado",MessageBoxButton.OK,MessageBoxImage.Information);
                return null;
            }

            using (var s = opendlg.OpenFile())
            {
                fileInbytes = new byte[s.Length];
                var numBytesToRead = (int) s.Length;
                var numBytesRead = 0;

                while (numBytesToRead > 0)
                {
                    var n = s.Read(fileInbytes, numBytesRead, numBytesToRead);

                    if (n == 0) break;
                    numBytesRead += n;

                    numBytesToRead -= n;
                }

                s.Close();

                return fileInbytes;
            }
        }


        /// <summary>
        /// Método que se dispara al cerrar la ventana
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Close(object sender, MouseButtonEventArgs e)
        {
            var parent = (Inventario)_parent;
            parent.Overlay.Visibility = Visibility.Hidden;
            Close();
        }

        
    }
}
